#ifndef _SDP_IMPL_BUILDER_H_
#define _SDP_IMPL_BUILDER_H_

#include <vector>
#include "../abnf/Rule.hpp"
#include "../abnf/Visitor.hpp"

using namespace abnf;

class Builder : 
	public Visitor 
{
public:
	 virtual void* visit(Rule_session_description* rule);
	 virtual void* visit(Rule_proto_version* rule);
	 virtual void* visit(Rule_origin_field* rule);
	 virtual void* visit(Rule_session_name_field* rule);
	 virtual void* visit(Rule_information_field* rule);
	 virtual void* visit(Rule_uri_field* rule);
	 virtual void* visit(Rule_email_fields* rule);
	 virtual void* visit(Rule_email_field* rule);
	 virtual void* visit(Rule_phone_fields* rule);
	 virtual void* visit(Rule_phone_field* rule);
	 virtual void* visit(Rule_connection_field* rule);
	 virtual void* visit(Rule_bandwidth_fields* rule);
	 virtual void* visit(Rule_bandwidth_field* rule);
	 virtual void* visit(Rule_time_fields* rule);
	 virtual void* visit(Rule_time_repeat_field* rule);
	 virtual void* visit(Rule_time_field* rule);
	 virtual void* visit(Rule_repeat_field* rule);
	 virtual void* visit(Rule_zone_adjustments* rule);
	 virtual void* visit(Rule_key_field* rule);
	 virtual void* visit(Rule_attribute_fields* rule);
	 virtual void* visit(Rule_attribute_field* rule);
	 virtual void* visit(Rule_gen_attribute* rule);
	 virtual void* visit(Rule_sctpmap_attr* rule);
	 virtual void* visit(Rule_sctpmap_number* rule);
	 virtual void* visit(Rule_app* rule);
	 virtual void* visit(Rule_streams* rule);
	 virtual void* visit(Rule_fingerprint_attribute* rule);
	 virtual void* visit(Rule_hash_func* rule);
	 virtual void* visit(Rule_fingerprint* rule);
	 virtual void* visit(Rule_extmap_attribute* rule);
	 virtual void* visit(Rule_extension_identifier* rule);
	 virtual void* visit(Rule_extension_name* rule);
	 virtual void* visit(Rule_direction* rule);
	 virtual void* visit(Rule_extension_attributes* rule);
	 virtual void* visit(Rule_candidate_attribute* rule);
	 virtual void* visit(Rule_foundation* rule);
	 virtual void* visit(Rule_component_id* rule);
	 virtual void* visit(Rule_transport* rule);
	 virtual void* visit(Rule_transport_extension* rule);
	 virtual void* visit(Rule_priority* rule);
	 virtual void* visit(Rule_cand_type* rule);
	 virtual void* visit(Rule_candidate_types* rule);
	 virtual void* visit(Rule_rel_addr* rule);
	 virtual void* visit(Rule_rel_port* rule);
	 virtual void* visit(Rule_extension_att* rule);
	 virtual void* visit(Rule_extension_att_name* rule);
	 virtual void* visit(Rule_extension_att_value* rule);
	 virtual void* visit(Rule_ice_char* rule);
	 virtual void* visit(Rule_crypto_attribute* rule);
	 virtual void* visit(Rule_tag* rule);
	 virtual void* visit(Rule_crypto_suite* rule);
	 virtual void* visit(Rule_key_params* rule);
	 virtual void* visit(Rule_key_param* rule);
	 virtual void* visit(Rule_key_method* rule);
	 virtual void* visit(Rule_key_method_ext* rule);
	 virtual void* visit(Rule_key_info* rule);
	 virtual void* visit(Rule_key_salt* rule);
	 virtual void* visit(Rule_key_lifetime* rule);
	 virtual void* visit(Rule_key_mki* rule);
	 virtual void* visit(Rule_key_mki_value* rule);
	 virtual void* visit(Rule_key_mki_length* rule);
	 virtual void* visit(Rule_session_param* rule);
	 virtual void* visit(Rule_mid_attr* rule);
	 virtual void* visit(Rule_identification_tag* rule);
	 virtual void* visit(Rule_group_attr* rule);
	 virtual void* visit(Rule_group_semantics* rule);
	 virtual void* visit(Rule_ssrc_attr* rule);
	 virtual void* visit(Rule_ssrc_id* rule);
	 virtual void* visit(Rule_ssrc_group_attr* rule);
	 virtual void* visit(Rule_ssrc_group_semantics* rule);
	 virtual void* visit(Rule_cname_attr* rule);
	 virtual void* visit(Rule_cname* rule);
	 virtual void* visit(Rule_previous_ssrc_attr* rule);
	 virtual void* visit(Rule_rtpmap_attr* rule);
	 virtual void* visit(Rule_name* rule);
	 virtual void* visit(Rule_rate* rule);
	 virtual void* visit(Rule_parameters* rule);
	 virtual void* visit(Rule_fmtp_attr* rule);
	 virtual void* visit(Rule_param_list* rule);
	 virtual void* visit(Rule_media_descriptions* rule);
	 virtual void* visit(Rule_media_description* rule);
	 virtual void* visit(Rule_media_field* rule);
	 virtual void* visit(Rule_username* rule);
	 virtual void* visit(Rule_sess_id* rule);
	 virtual void* visit(Rule_sess_version* rule);
	 virtual void* visit(Rule_nettype* rule);
	 virtual void* visit(Rule_addrtype* rule);
	 virtual void* visit(Rule_email_address* rule);
	 virtual void* visit(Rule_address_and_comment* rule);
	 virtual void* visit(Rule_dispname_and_address* rule);
	 virtual void* visit(Rule_phone_number* rule);
	 virtual void* visit(Rule_phone* rule);
	 virtual void* visit(Rule_connection_address* rule);
	 virtual void* visit(Rule_unicast_address* rule);
	 virtual void* visit(Rule_bwtype* rule);
	 virtual void* visit(Rule_bandwidth* rule);
	 virtual void* visit(Rule_start_time* rule);
	 virtual void* visit(Rule_stop_time* rule);
	 virtual void* visit(Rule_time* rule);
	 virtual void* visit(Rule_repeat_interval* rule);
	 virtual void* visit(Rule_typed_time* rule);
	 virtual void* visit(Rule_fixed_len_time_unit* rule);
	 virtual void* visit(Rule_key_type* rule);
	 virtual void* visit(Rule_prompt_key_type* rule);
	 virtual void* visit(Rule_clear_key_type* rule);
	 virtual void* visit(Rule_base64_key_type* rule);
	 virtual void* visit(Rule_uri_key_type* rule);
	 virtual void* visit(Rule_base64* rule);
	 virtual void* visit(Rule_base64_unit* rule);
	 virtual void* visit(Rule_base64_pad* rule);
	 virtual void* visit(Rule_base64_char* rule);
	 virtual void* visit(Rule_attribute* rule);
	 virtual void* visit(Rule_att_field* rule);
	 virtual void* visit(Rule_att_value* rule);
	 virtual void* visit(Rule_media* rule);
	 virtual void* visit(Rule_fmt* rule);
	 virtual void* visit(Rule_proto* rule);
	 virtual void* visit(Rule_port* rule);
	 virtual void* visit(Rule_number_of_ports* rule);
	 virtual void* visit(Rule_IP4_multicast* rule);
	 virtual void* visit(Rule_m1* rule);
	 virtual void* visit(Rule_IP6_multicast* rule);
	 virtual void* visit(Rule_ttl* rule);
	 virtual void* visit(Rule_FQDN* rule);
	 virtual void* visit(Rule_email_safe* rule);
	 virtual void* visit(Rule_URI* rule);
	 virtual void* visit(Rule_hier_part* rule);
	 virtual void* visit(Rule_URI_reference* rule);
	 virtual void* visit(Rule_absolute_URI* rule);
	 virtual void* visit(Rule_relative_ref* rule);
	 virtual void* visit(Rule_relative_part* rule);
	 virtual void* visit(Rule_scheme* rule);
	 virtual void* visit(Rule_authority* rule);
	 virtual void* visit(Rule_userinfo* rule);
	 virtual void* visit(Rule_host* rule);
	 virtual void* visit(Rule_IP_literal* rule);
	 virtual void* visit(Rule_IPvFuture* rule);
	 virtual void* visit(Rule_IPv6address* rule);
	 virtual void* visit(Rule_h16* rule);
	 virtual void* visit(Rule_ls32* rule);
	 virtual void* visit(Rule_IPv4address* rule);
	 virtual void* visit(Rule_dec_octet* rule);
	 virtual void* visit(Rule_reg_name* rule);
	 virtual void* visit(Rule_path* rule);
	 virtual void* visit(Rule_path_abempty* rule);
	 virtual void* visit(Rule_path_absolute* rule);
	 virtual void* visit(Rule_path_noscheme* rule);
	 virtual void* visit(Rule_path_rootless* rule);
	 virtual void* visit(Rule_path_empty* rule);
	 virtual void* visit(Rule_segment* rule);
	 virtual void* visit(Rule_segment_nz* rule);
	 virtual void* visit(Rule_segment_nz_nc* rule);
	 virtual void* visit(Rule_pchar* rule);
	 virtual void* visit(Rule_query* rule);
	 virtual void* visit(Rule_fragment* rule);
	 virtual void* visit(Rule_pct_encoded* rule);
	 virtual void* visit(Rule_unreserved* rule);
	 virtual void* visit(Rule_reserved* rule);
	 virtual void* visit(Rule_gen_delims* rule);
	 virtual void* visit(Rule_sub_delims* rule);
	 virtual void* visit(Rule_addr_spec* rule);
	 virtual void* visit(Rule_local_part* rule);
	 virtual void* visit(Rule_domain* rule);
	 virtual void* visit(Rule_domain_literal* rule);
	 virtual void* visit(Rule_dcontent* rule);
	 virtual void* visit(Rule_dtext* rule);
	 virtual void* visit(Rule_NO_WS_CTL* rule);
	 virtual void* visit(Rule_quoted_pair* rule);
	 virtual void* visit(Rule_text* rule);
	 virtual void* visit(Rule_FWS* rule);
	 virtual void* visit(Rule_comment* rule);
	 virtual void* visit(Rule_ccontent* rule);
	 virtual void* visit(Rule_ctext* rule);
	 virtual void* visit(Rule_dot_atom* rule);
	 virtual void* visit(Rule_dot_atom_text* rule);
	 virtual void* visit(Rule_atext* rule);
	 virtual void* visit(Rule_integer* rule);
	 virtual void* visit(Rule_alpha_numeric* rule);
	 virtual void* visit(Rule_decimal_uchar* rule);
	 virtual void* visit(Rule_decimal_uchar_1xx* rule);
	 virtual void* visit(Rule_decimal_uchar_2xx* rule);
	 virtual void* visit(Rule_decimal_uchar_25x* rule);
	 virtual void* visit(Rule_BIT* rule);
	 virtual void* visit(Rule_CHAR* rule);
	 virtual void* visit(Rule_CR* rule);
	 virtual void* visit(Rule_CTL* rule);
	 virtual void* visit(Rule_HEXDIG* rule);
	 virtual void* visit(Rule_HTAB* rule);
	 virtual void* visit(Rule_LF* rule);
	 virtual void* visit(Rule_LWSP* rule);
	 virtual void* visit(Rule_OCTET* rule);
	 virtual void* visit(Rule_SP* rule);
	 virtual void* visit(Rule_VCHAR* rule);
	 virtual void* visit(Rule_quoted_string* rule);
	 virtual void* visit(Rule_qcontent* rule);
	 virtual void* visit(Rule_qtext* rule);
	 virtual void* visit(Rule_obs_local_part* rule);
	 virtual void* visit(Rule_obs_domain* rule);
	 virtual void* visit(Rule_obs_FWS* rule);
	 virtual void* visit(Rule_obs_qp* rule);
	 virtual void* visit(Rule_obs_text* rule);
	 virtual void* visit(Rule_obs_char* rule);
	 virtual void* visit(Rule_CFWS* rule);
	 virtual void* visit(Rule_WSP* rule);
	 virtual void* visit(Rule_atom* rule);
	 virtual void* visit(Rule_word* rule);
	 virtual void* visit(Rule_extn_addr* rule);
	 virtual void* visit(Rule_non_ws_string* rule);
	 virtual void* visit(Rule_byte_string* rule);
	 virtual void* visit(Rule_CRLF* rule);
	 virtual void* visit(Rule_token* rule);
	 virtual void* visit(Rule_ALPHA* rule);
	 virtual void* visit(Rule_DIGIT* rule);
	 virtual void* visit(Rule_POS_DIGIT* rule);
	 virtual void* visit(Rule_DQUOTE* rule);
	 virtual void* visit(Rule_EQUALS* rule);

	 virtual void* visit(Terminal_StringValue* value);
	 virtual void* visit(Terminal_NumericValue* value);
	 
protected:
	void* visitRules(const std::vector<Rule*>& rules);	 

	// Inherited via Visitor
	virtual void * visit(Rule_source_filter_attr * rule) override;
	virtual void * visit(Rule_filter_mode * rule) override;
	virtual void * visit(Rule_filter_spec * rule) override;
	virtual void * visit(Rule_address_types * rule) override;
	virtual void * visit(Rule_dest_address * rule) override;
	virtual void * visit(Rule_src_list * rule) override;
	virtual void * visit(Rule_timestamp_refclk_attr * rule) override;
	virtual void * visit(Rule_clksrc * rule) override;
	virtual void * visit(Rule_clksrc_ext * rule) override;
	virtual void * visit(Rule_clksrc_param_name * rule) override;
	virtual void * visit(Rule_clksrc_param_value * rule) override;
	virtual void * visit(Rule_ntp * rule) override;
	virtual void * visit(Rule_ntp_server_addr * rule) override;
	virtual void * visit(Rule_ptp * rule) override;
	virtual void * visit(Rule_ptp_version * rule) override;
	virtual void * visit(Rule_ptp_version_ext * rule) override;
	virtual void * visit(Rule_ptp_server * rule) override;
	virtual void * visit(Rule_ptp_gmid * rule) override;
	virtual void * visit(Rule_ptp_domain * rule) override;
	virtual void * visit(Rule_ptp_domain_name * rule) override;
	virtual void * visit(Rule_ptp_domain_char * rule) override;
	virtual void * visit(Rule_ptp_domain_nmbr * rule) override;
	virtual void * visit(Rule_ptp_domain_dgts * rule) override;
	virtual void * visit(Rule_ptp_domain_n1 * rule) override;
	virtual void * visit(Rule_ptp_domain_n2 * rule) override;
	virtual void * visit(Rule_ptp_domain_n3 * rule) override;
	virtual void * visit(Rule_gps * rule) override;
	virtual void * visit(Rule_gal * rule) override;
	virtual void * visit(Rule_glonass * rule) override;
	virtual void * visit(Rule_local * rule) override;
	virtual void * visit(Rule_private * rule) override;
	virtual void * visit(Rule_media_clksrc_attr * rule) override;
	virtual void * visit(Rule_media_clkid * rule) override;
	virtual void * visit(Rule_media_clktag * rule) override;
	virtual void * visit(Rule_mediaclock * rule) override;
	virtual void * visit(Rule_mediaclock_ext * rule) override;
	virtual void * visit(Rule_mediaclock_param_name * rule) override;
	virtual void * visit(Rule_mediaclock_param_value * rule) override;
	virtual void * visit(Rule_sender * rule) override;
	virtual void * visit(Rule_direct * rule) override;
	virtual void * visit(Rule_fsrate * rule) override;
	virtual void * visit(Rule_ieee1722_streamid * rule) override;
	virtual void * visit(Rule_avb_stream_id * rule) override;
	virtual void * visit(Rule_hostport * rule) override;
	virtual void * visit(Rule_EUI64 * rule) override;
};

#endif
